<template>
  <div class="call-screen-container">
    <header class="header">
      <div class="logo-container">
        <img src="../../assets/logo.png" alt="Logo" class="logo">
        <h1>排队叫号系统</h1>
      </div>
      <div class="datetime">{{ currentDateTime }}</div>
    </header>

    <main class="content">
      <div class="left-panel">
        <!-- 当前叫号 -->
        <div class="current-call-container">
          <div class="panel-title">当前叫号</div>
          <div class="current-call" :class="{ 'animated': showAnimation }">
            <div class="ticket-number">{{ currentCall.ticketNumber || '等待叫号' }}</div>
                <div class="call-info">
              <div class="business-type">{{ currentCall.businessType }}</div>
              <div class="window-number">请到 {{ currentCall.windowNumber }} 号窗口</div>
                  </div>
                  </div>
                </div>

        <!-- 当前排队 -->
        <div class="current-queue-container">
          <div class="panel-title">当前排队</div>
          <div class="queue-list" :class="{ 'rotating': showQueueAnimation }">
            <div v-for="item in queueList" :key="item.id" class="queue-item">
              <div class="queue-number">{{ item.ticketNumber }}</div>
              <div class="queue-info">
                <div class="queue-business">{{ item.businessType }}</div>
                <div class="queue-time">取号时间: {{ item.createTime }}</div>
              </div>
              <div class="queue-wait-time">已等待 {{ formatTime(item.waitTime) }}</div>
            </div>
            <div v-if="queueList.length === 0" class="empty-queue">
              <div class="empty-text">暂无排队人员</div>
            </div>
          </div>
          <!-- 页码指示器 -->
          <div class="pagination-indicator" v-if="queueList.length > 0 && hiddenQueueList.length > 0">
            <span
              v-for="(_, i) in Math.ceil((queueList.length + hiddenQueueList.length) / queueDisplayCount)"
              :key="i"
              class="indicator-dot"
              :class="{ 'active': i === 0 }"
            ></span>
              </div>
            </div>

        <!-- 历史叫号 -->
        <div class="history-call-container">
          <div class="panel-title">历史叫号</div>
          <div class="history-list" :class="{ 'rotating': showHistoryAnimation }">
            <div v-for="item in callHistory" :key="item.ticketNumber" class="history-item">
              <div class="history-number">{{ item.ticketNumber }}</div>
                    <div class="history-info">
                <div class="history-business">{{ item.businessType }}</div>
                <div class="history-window">{{ item.windowNumber }}号窗口</div>
                    </div>
              <div class="history-details">
                <div class="history-time">{{ item.callTime }}</div>
                <div class="history-status" :class="getHistoryStatusClass(item.status)">
                  {{ getHistoryStatusText(item.status) }}
            </div>
          </div>
            </div>
          </div>
          <!-- 页码指示器 -->
          <div class="pagination-indicator" v-if="callHistory.length > 0 && hiddenCallHistory.length > 0">
            <span
              v-for="(_, i) in Math.ceil((callHistory.length + hiddenCallHistory.length) / historyDisplayCount)"
              :key="i"
              class="indicator-dot"
              :class="{ 'active': i === 0 }"
            ></span>
          </div>
        </div>
      </div>

      <div class="right-panel">
        <!-- 窗口状态 -->
        <div class="window-status-container">
          <div class="panel-title">窗口状态</div>
          <div class="window-status-list" :class="{ 'rotating': showWindowAnimation }">
            <div v-for="status in currentWindowPage" :key="status.id" class="window-status-item">
              <div class="window-name">{{ status.name }}</div>
              <div class="window-info">
                <div class="window-staff">办理人员: {{ status.staffName }}</div>
                <div class="window-type">业务类型: {{ status.businessType }}</div>
                  </div>
              <div class="window-queue-info">
                <div class="window-current">当前号: <span>{{ status.currentNumber || '暂无' }}</span></div>
                <div class="window-waiting">等待人数: <span>{{ status.waitingCount }}</span></div>
                <div class="window-average">平均等待: <span>{{ formatTime(status.averageWaitTime) }}</span></div>
                  </div>
              <div class="window-status-indicator" :class="getStatusClass(status.status)">{{ getStatusText(status.status) }}</div>
                </div>
              </div>
          <!-- 页码指示器 -->
          <div class="pagination-indicator" v-if="windowPages.length > 1">
            <span
              v-for="(page, index) in windowPages"
              :key="index"
              class="indicator-dot"
              :class="{ 'active': index === windowCurrentPage }"
            ></span>
              </div>
            </div>

        <!-- 综合统计 -->
        <div class="stats-container">
          <div class="panel-title">综合统计</div>
          <div class="stats-list">
            <div class="stats-item">
              <div class="stats-label">总等待人数</div>
              <div class="stats-value" :key="'wait-'+queueStats.totalWaiting">{{ queueStats.totalWaiting }}</div>
                    </div>
            <div class="stats-item">
              <div class="stats-label">今日已服务</div>
              <div class="stats-value" :key="'served-'+queueStats.totalServed">{{ queueStats.totalServed }}</div>
              </div>
            <div class="stats-item">
              <div class="stats-label">平均等待时间</div>
              <div class="stats-value" :key="'avg-'+queueStats.averageWaitTime">{{ formatTime(queueStats.averageWaitTime) }}</div>
            </div>
          </div>
        </div>

        <!-- 通知公告 -->
        <div class="notices-container">
          <div class="panel-title">通知公告</div>
          <div class="notice-list" :class="{ 'rotating': showNoticeAnimation }">
            <div v-for="notice in currentNotices" :key="notice.title" class="notice-item">
              <div class="notice-title">{{ notice.title }}</div>
              <div class="notice-content">{{ notice.content }}</div>
            </div>
          </div>
          <!-- 页码指示器 -->
          <div class="pagination-indicator" v-if="noticeList.length > noticeDisplayCount">
            <span
              v-for="(_, i) in noticeList"
              :key="i"
              class="indicator-dot"
              :class="{ 'active': i === noticeCurrentIndex }"
            ></span>
          </div>
        </div>
      </div>
    </main>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch, onBeforeUnmount } from 'vue'
import axios from "axios";
import {getMinutesDifference} from "@/utils/date";
window.addEventListener('beforeunload', function (event) {
  // 自定义提示信息（部分浏览器会忽略自定义消息）
  event.preventDefault();
  event.returnValue = ''; // 某些浏览器需要设置 returnValue
  socket.close();
});
let sessionId = null;
// 创建 WebSocket 连接
const socket = new WebSocket('ws://127.0.0.1:8080/api/ws/call-screen');

// 监听连接成功事件
socket.addEventListener('open', function (event) {
  console.log('WebSocket 连接已建立');
});

// 监听接收消息事件
socket.addEventListener('message', function (event) {
  console.log('收到消息:', event.data);
  // 如果需要解析 JSON 数据
  try {
    const data = JSON.parse(event.data);
    if (data.type === 'connect') {
      sessionId = data.data;
      console.log('sessionId:', sessionId);
    } else if (data.type === 'reFreshData') {
      refreshData();
    }
  } catch (error) {
    console.error('消息解析失败:', error);
  }
});


// 监听错误事件
socket.addEventListener('error', function (event) {
  console.error('WebSocket 错误:', event);
});

// 监听连接关闭事件
socket.addEventListener('close', function (event) {
  console.log('WebSocket 连接已关闭:', event);
});

// 当前日期时间
const currentDateTime = ref('')
let dateTimer = null

// 当前叫号信息
let currentCall = reactive({
  ticketNumber: '',
  businessType: '',
  windowNumber: '',
  timestamp: null
})
let businessTypeMap = new Map;
function initData() {
  axios.get("/service-types/getList", {
    params: {
      "pageNum": 1,
      "pageSize": 100,
      "status": 1,
    }
  }).then(res => {
    res.data.data.list.forEach(item => {
      businessTypeMap.set(item.id, item);
    })
    refreshData();
  });
}
initData();

function refreshData() {
  axios("/callScreen/geCallScreenData").then(res => {
    // 处理当前叫号
    dealCurCall(res);
    // 处理窗口状态
    dealWindowData(res);
    //  处理当前排队
    dealCurWaitingQueue(res)
    // 处理当日所有队列
    dealAllQueue(res);
    // 处理通知公告
    noticeList.value = []
    if (res.data.data.noticeList && res.data.data.noticeList.length > 0) {
      res.data.data.noticeList.forEach(item => {
        noticeList.value.push(item);
      })
    }
  });
}
function dealAllQueue(res) {
  callHistory.value = [];
  let totalWaiting = 0;
  let totalServed = 0;
  let averageWaitTime = 0;
  if (res.data.data.allQueue && res.data.data.allQueue.length > 0) {
    res.data.data.allQueue.forEach(item => {
      if (item.status === 'WAITING') {
        totalWaiting++;
      } else if (item.status === 'COMPLETED') {
        totalServed++;
        averageWaitTime += getMinutesDifference(item.createTime, item.callTime);
        addCallHistory(item);
      } else {
        addCallHistory(item);
      }
    })
    if (totalServed) {
      averageWaitTime = Math.floor(averageWaitTime / totalServed);
    }
  }
  // 综合统计
  queueStats.totalWaiting = totalWaiting;
  queueStats.totalServed = totalServed;
  queueStats.averageWaitTime = averageWaitTime;
}
function addCallHistory(data) {
  data.windowNumber = data.windowId;
  data.businessType = businessTypeMap.get(data.serviceTypeId).name;
  callHistory.value.push(data);
}
function dealCurWaitingQueue(res) {
  queueList.value = [];
  if (res.data.data.queueList && res.data.data.queueList.length > 0) {
    res.data.data.queueList.forEach(item => {
      let data = {
        id: item.id,
        ticketNumber: item.ticketNumber,
        businessType: businessTypeMap.get(item.serviceTypeId).name,
        waitTime: getMinutesDifference(item.createTime, item.callTime),
        createTime: item.createTime
      }
      queueList.value.push(data)
    })
  }
}
function dealWindowData(res) {
  if (res.data.data.queueStatus.list && res.data.data.queueStatus.list.length > 0) {
    queueStatus.value = [];
    res.data.data.queueStatus.list.forEach(item => {
      let data = {
        id: item.id,
        name: item.name,
        staffName: item.staffName,
        currentNumber: item.currentNumber,
        waitingCount: item.waitingCount,
        averageWaitTime: item.averageWaitTime,
        status: item.status
      }
      if (item.serviceTypeId) {
        data.businessType = businessTypeMap.get(item.serviceTypeId).name
      }
      queueStatus.value.push(data)
    })
  }
}

function dealCurCall(res) {
  if (res.data.data.currentCall) {
    currentCall.ticketNumber = res.data.data.currentCall.ticketNumber
    currentCall.businessType = businessTypeMap.get(res.data.data.currentCall.serviceTypeId).name
    currentCall.windowNumber = res.data.data.currentCall.windowId
  } else {
    currentCall.ticketNumber = ''
    currentCall.businessType = ''
    currentCall.windowNumber = ''
  }
}
// 当前排队列表
const queueList = ref([

])

// 已排队但未显示的队列
const hiddenQueueList = ref([

])

// 轮播相关配置
const queueDisplayCount = 3 // 一次显示的排队数量
const queueRotationInterval = 6000 // 排队轮播间隔，6秒
let queueRotationTimer = null
const queueCurrentIndex = ref(0)

// 历史叫号列表
const callHistory = ref([

])

// 已叫号但未显示的历史记录
const hiddenCallHistory = ref([

])

// 历史记录轮播配置
const historyDisplayCount = 5 // 一次显示的历史记录数量
const historyRotationInterval = 8000 // 历史记录轮播间隔，8秒
let historyRotationTimer = null
const historyCurrentIndex = ref(0)

// 窗口状态
const queueStatus = ref([
  {
    id: 1,
    name: '1号窗口',
    status: 'serving', // serving, waiting, closed
    currentNumber: 'A124',
    staffName: '张三',
    businessType: '个人业务',
    waitingCount: 5,
    averageWaitTime: 10 // 分钟
  },
  {
    id: 2,
    name: '2号窗口',
    status: 'waiting', // serving, waiting, closed
    currentNumber: null,
    staffName: '李四',
    businessType: '个人业务',
    waitingCount: 2,
    averageWaitTime: 8 // 分钟
  },
  {
    id: 3,
    name: '3号窗口',
    status: 'serving', // serving, waiting, closed
    currentNumber: 'A123',
    staffName: '王五',
    businessType: '个人业务',
    waitingCount: 3,
    averageWaitTime: 12 // 分钟
  },
  {
    id: 4,
    name: '4号窗口',
    status: 'closed', // serving, waiting, closed
    currentNumber: null,
    staffName: '休息中',
    businessType: '个人业务',
    waitingCount: 0,
    averageWaitTime: 0 // 分钟
  },
  {
    id: 5,
    name: '5号窗口',
    status: 'serving', // serving, waiting, closed
    currentNumber: 'B057',
    staffName: '赵六',
    businessType: '企业业务',
    waitingCount: 6,
    averageWaitTime: 15 // 分钟
  },
  {
    id: 6,
    name: '6号窗口',
    status: 'serving', // serving, waiting, closed
    currentNumber: 'C033',
    staffName: '钱七',
    businessType: '信贷业务',
    waitingCount: 4,
    averageWaitTime: 20 // 分钟
  }
])

// 窗口状态轮播配置
const windowDisplayCount = 4 // 一次显示的窗口数量
const windowRotationInterval = 5000 // 窗口轮播间隔，5秒
let windowRotationTimer = null

// 当前显示的窗口页码
const windowCurrentPage = ref(0)
// 计算窗口分页
const windowPages = computed(() => {
  const pages = []
  const total = queueStatus.value.length
  const pageCount = Math.ceil(total / windowDisplayCount)

  for (let i = 0; i < pageCount; i++) {
    const start = i * windowDisplayCount
    const end = Math.min(start + windowDisplayCount, total)
    pages.push(queueStatus.value.slice(start, end))
  }

  return pages
})

// 获取当前显示的窗口列表
const currentWindowPage = computed(() => {
  if (windowPages.value.length === 0) return []
  return windowPages.value[windowCurrentPage.value]
})

// 通知公告
const noticeList = ref([
  {
    title: '业务办理须知',
    content: '请各位办理业务时，准备好有效证件和相关材料，以提高办理效率。'
  },
  {
    title: '系统升级通知',
    content: '本系统将于本周六晚22:00-次日凌晨2:00进行系统升级维护，期间暂停服务，敬请谅解。'
  },
  {
    title: '新业务上线',
    content: '即日起，本网点新增"企业开户一站式"服务，欢迎咨询办理。'
  },
  {
    title: '节假日安排',
    content: '国庆期间本网点照常营业，请广大客户合理安排办理时间。'
  },
  {
    title: '排队预约提醒',
    content: '为节省您的等待时间，建议提前通过手机银行或官方网站进行业务预约。'
  }
])

// 通知轮播配置
const noticeDisplayCount = 2 // 一次显示的通知数量
const noticeRotationInterval = 10000 // 通知轮播间隔，10秒
let noticeRotationTimer = null
const noticeCurrentIndex = ref(0)

// 获取当前显示的通知
const currentNotices = computed(() => {
  const start = noticeCurrentIndex.value
  const end = Math.min(start + noticeDisplayCount, noticeList.value.length)

  // 如果不足显示数量，则从头补充
  if (end - start < noticeDisplayCount) {
    return [
      ...noticeList.value.slice(start),
      ...noticeList.value.slice(0, noticeDisplayCount - (end - start))
    ]
  }

  return noticeList.value.slice(start, end)
})

// 统计数据轮播
const statsUpdateInterval = 12000 // 统计数据更新间隔，12秒
let statsUpdateTimer = null

// 统计数据
const queueStats = reactive({
  totalWaiting: 0,
  totalServed: 0,
  averageWaitTime: 0 // 分钟
})

// 动画控制
const showAnimation = ref(false)
// 队列轮播动画
const showQueueAnimation = ref(false)
// 历史轮播动画
const showHistoryAnimation = ref(false)
// 窗口轮播动画
const showWindowAnimation = ref(false)
// 通知轮播动画
const showNoticeAnimation = ref(false)

// 轮播队列中的内容
const rotateQueueList = () => {
  showQueueAnimation.value = true

  setTimeout(() => {
    // 合并显示队列和隐藏队列
    const allQueues = [...queueList.value, ...hiddenQueueList.value]

    // 如果队列中有数据就轮换
    if (allQueues.length > queueDisplayCount) {
      // 将第一个移到隐藏队列
      const firstItem = queueList.value.shift()
      hiddenQueueList.value.push(firstItem)

      // 将隐藏队列的第一个移到显示队列
      const newItem = hiddenQueueList.value.shift()
      queueList.value.push(newItem)

      // 更新等待时间
      queueList.value.forEach(item => {
        item.waitTime += 0.1 // 增加一点等待时间
      })

      hiddenQueueList.value.forEach(item => {
        item.waitTime += 0.1 // 增加一点等待时间
      })
    }

    showQueueAnimation.value = false
  }, 500)
}

// 轮播历史叫号记录
const rotateHistoryList = () => {
  showHistoryAnimation.value = true

  setTimeout(() => {
    // 合并显示历史和隐藏历史
    const allHistory = [...callHistory.value, ...hiddenCallHistory.value]

    // 如果历史中有足够数据就轮换
    if (allHistory.length > historyDisplayCount) {
      // 将最后一个移到隐藏历史
      const lastItem = callHistory.value.pop()
      hiddenCallHistory.value.unshift(lastItem)

      // 将隐藏历史的第一个移到显示历史的最前面
      const newItem = hiddenCallHistory.value.pop()
      callHistory.value.unshift(newItem)
    }

    showHistoryAnimation.value = false
  }, 500)
}

// 轮播窗口状态
const rotateWindowStatus = () => {
  showWindowAnimation.value = true

  setTimeout(() => {
    // 切换到下一页
    windowCurrentPage.value = (windowCurrentPage.value + 1) % windowPages.value.length

    // 更新状态
    queueStatus.value.forEach(status => {
      // 随机更新一些数据，模拟真实情况
      if (Math.random() > 0.8) {
        status.waitingCount = Math.max(0, status.waitingCount + (Math.random() > 0.5 ? 1 : -1))
      }

      if (Math.random() > 0.9 && status.status === 'serving') {
        status.averageWaitTime = Math.max(1, status.averageWaitTime + (Math.random() > 0.5 ? 1 : -1))
      }
    })

    showWindowAnimation.value = false
  }, 500)
}

// 轮播通知公告
const rotateNotices = () => {
  showNoticeAnimation.value = true

  setTimeout(() => {
    // 切换到下一组通知
    noticeCurrentIndex.value = (noticeCurrentIndex.value + 1) % noticeList.value.length

    showNoticeAnimation.value = false
  }, 500)
}

// 更新统计数据
const updateStats = () => {
  // 随机更新统计数据
  if (Math.random() > 0.5) {
    queueStats.totalWaiting = Math.max(0, queueStats.totalWaiting + (Math.random() > 0.6 ? 1 : -1))
  }

  if (Math.random() > 0.3) {
    queueStats.totalServed += Math.floor(Math.random() * 3) + 1
  }

  if (Math.random() > 0.7) {
    queueStats.averageWaitTime = Math.max(1, queueStats.averageWaitTime + (Math.random() > 0.5 ? 1 : -1))
  }
}

// 更新当前日期时间
const updateDateTime = () => {
  const now = new Date()
      const year = now.getFullYear()
      const month = (now.getMonth() + 1).toString().padStart(2, '0')
      const date = now.getDate().toString().padStart(2, '0')
  const hours = now.getHours().toString().padStart(2, '0')
  const minutes = now.getMinutes().toString().padStart(2, '0')
  const seconds = now.getSeconds().toString().padStart(2, '0')
      const day = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'][now.getDay()]

  currentDateTime.value = `${year}年${month}月${date}日 ${hours}:${minutes}:${seconds} ${day}`
}

// 格式化时间
const formatTime = (minutes) => {
      if (!minutes || minutes <= 0) return '无需等待'

      if (minutes < 60) {
    return `${minutes}分钟`
      } else {
        const hours = Math.floor(minutes / 60)
    const mins = minutes % 60
    return `${hours}小时${mins > 0 ? `${mins}分钟` : ''}`
  }
}

// 根据状态获取样式类
const getStatusClass = (status) => {
  const statusMap = {
    'serving': 'status-serving',
    'waiting': 'status-waiting',
    'closed': 'status-closed'
  }

  return statusMap[status] || 'status-waiting'
}

// 根据状态获取文本
const getStatusText = (status) => {
  const statusMap = {
    'serving': '正在服务',
    'waiting': '等待中',
    'closed': '暂停服务'
  }

  return statusMap[status] || '等待中'
}

// 历史叫号状态样式类
const getHistoryStatusClass = (status) => {
  const statusMap = {
    'completed': 'status-completed',
    'serving': 'status-serving',
    'missed': 'status-missed'
  }

  return statusMap[status] || 'status-completed'
}

// 历史叫号状态文本
const getHistoryStatusText = (status) => {
  const statusMap = {
    'completed': '已完成',
    'serving': '办理中',
    'missed': '未到场'
  }

  return statusMap[status] || '已完成'
}

// 自动更新等待时间
const waitTimeUpdateInterval = 60000 // 每分钟更新一次等待时间
let waitTimeUpdateTimer = null

const updateWaitTimes = () => {
  // 更新排队列表的等待时间
  queueList.value.forEach(item => {
    item.waitTime += 1
  })

  hiddenQueueList.value.forEach(item => {
    item.waitTime += 1
  })
}


// 安全地请求全屏
const requestFullscreenSafely = () => {
  try {
    // 创建一个按钮让用户点击以满足用户交互要求
    const fullscreenButton = document.createElement('button')
    fullscreenButton.textContent = '点击进入全屏模式'
    fullscreenButton.className = 'fullscreen-button'
    fullscreenButton.style.cssText = 'position: fixed; top: 10px; right: 10px; z-index: 9999; padding: 10px; background-color: #409EFF; color: white; border: none; border-radius: 4px; cursor: pointer;'

    fullscreenButton.onclick = () => {
      try {
        const elem = document.documentElement
        if (elem.requestFullscreen) {
          elem.requestFullscreen().catch(e => console.error('全屏请求失败:', e))
        } else if (elem.mozRequestFullScreen) { /* Firefox */
          elem.mozRequestFullScreen()
        } else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
          elem.webkitRequestFullscreen()
        } else if (elem.msRequestFullscreen) { /* IE/Edge */
          elem.msRequestFullscreen()
        }

        // 请求成功后移除按钮
        document.body.removeChild(fullscreenButton)
      } catch (error) {
        console.error('请求全屏失败:', error)
        // 尝试移除按钮
        try {
          document.body.removeChild(fullscreenButton)
        } catch (e) {
          console.error('移除全屏按钮失败:', e)
        }
      }
    }

    // 添加按钮到页面
    document.body.appendChild(fullscreenButton)

    // 5秒后自动隐藏按钮（如果用户没有点击）
    setTimeout(() => {
      if (document.body.contains(fullscreenButton)) {
        fullscreenButton.style.opacity = '0.5'

        // 再5秒后移除按钮
        setTimeout(() => {
          if (document.body.contains(fullscreenButton)) {
            document.body.removeChild(fullscreenButton)
          }
        }, 5000)
      }
    }, 5000)
  } catch (error) {
    console.error('创建全屏按钮失败:', error)
  }
}
</script>

<style scoped>
/* 全局设置 */
.call-screen-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f0f2f5;
  overflow: hidden;
  font-family: "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(to right, #1565C0, #1976d2);
  color: white;
  padding: 15px 20px;
  box-shadow: 0 4px 15px rgba(0,0,0,0.15);
  z-index: 10;
}

.logo-container {
  display: flex;
  align-items: center;
}

.logo {
  height: 50px;
  margin-right: 20px;
  filter: drop-shadow(0 2px 5px rgba(0,0,0,0.2));
}

.logo-container h1 {
  font-size: 28px;
  font-weight: bold;
  text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

.datetime {
  font-size: 22px;
  font-weight: 500;
  background-color: rgba(255,255,255,0.15);
  padding: 8px 15px;
  border-radius: 20px;
  backdrop-filter: blur(5px);
}

.content {
  flex: 1;
  display: flex;
  padding: 20px;
  gap: 20px;
  overflow: hidden;
}

.left-panel, .right-panel {
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
}

.left-panel {
  flex: 3;
}

.right-panel {
  flex: 2;
}

.panel-title {
  font-size: 24px;
  color: #1976d2;
  font-weight: bold;
  margin-bottom: 15px;
  border-bottom: 2px solid #1976d2;
  padding-bottom: 10px;
  position: relative;
}

.panel-title::after {
  content: '';
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 50px;
  height: 2px;
  background-color: #f44336;
}

/* 隐藏所有滚动条 */
::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

/* 当前叫号样式 */
.current-call-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  flex: 1;
  overflow: hidden;
  transition: all 0.3s ease;
}

.current-call-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.current-call {
  display: flex;
  align-items: center;
  padding: 25px;
  background: linear-gradient(135deg, #e3f2fd, #bbdefb);
  border-radius: 12px;
  border-left: 5px solid #1976d2;
  box-shadow: inset 0 0 20px rgba(25, 118, 210, 0.1);
}

.current-call.animated {
  animation: callAnimation 3s ease;
}

@keyframes callAnimation {
  0% {
    background: linear-gradient(135deg, #e3f2fd, #bbdefb);
    transform: scale(1);
    box-shadow: 0 0 20px rgba(25, 118, 210, 0.1);
  }
  20% {
    background: linear-gradient(135deg, #bbdefb, #90caf9);
    transform: scale(1.05);
    box-shadow: 0 0 30px rgba(25, 118, 210, 0.3);
  }
  40% {
    background: linear-gradient(135deg, #90caf9, #64b5f6);
    transform: scale(1);
    box-shadow: 0 0 40px rgba(25, 118, 210, 0.4);
  }
  60% {
    background: linear-gradient(135deg, #bbdefb, #90caf9);
    transform: scale(1.05);
    box-shadow: 0 0 30px rgba(25, 118, 210, 0.3);
  }
  80% {
    background: linear-gradient(135deg, #e3f2fd, #bbdefb);
    transform: scale(1);
    box-shadow: 0 0 20px rgba(25, 118, 210, 0.1);
  }
  100% {
    background: linear-gradient(135deg, #e3f2fd, #bbdefb);
    transform: scale(1);
    box-shadow: 0 0 20px rgba(25, 118, 210, 0.1);
  }
}

.ticket-number {
  font-size: 68px;
  font-weight: bold;
  color: #f44336;
  margin-right: 30px;
  min-width: 200px;
  text-align: center;
  text-shadow: 2px 2px 4px rgba(0,0,0,0.1);
  animation: pulse 2s infinite ease-in-out;
}

@keyframes pulse {
  0% { transform: scale(1); }
  50% { transform: scale(1.03); }
  100% { transform: scale(1); }
}

.call-info {
  flex: 1;
}

.business-type {
  font-size: 36px;
  color: #1976d2;
  margin-bottom: 15px;
  font-weight: 600;
}

.window-number {
  font-size: 32px;
  color: #333;
  font-weight: 500;
}

/* 当前排队样式 */
.current-queue-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  flex: 1;
  overflow: hidden;
  transition: all 0.3s ease;
}

.current-queue-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.queue-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: hidden;
  max-height: calc(100% - 50px);
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.queue-item {
  display: flex;
  align-items: center;
  padding: 15px;
  background: linear-gradient(135deg, #fff3e0, #ffe0b2);
  border-radius: 10px;
  border-left: 4px solid #ff9800;
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
  transition: all 0.3s ease;
}

.queue-item:hover {
  transform: translateX(5px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.queue-number {
  font-size: 26px;
  font-weight: bold;
  color: #ff9800;
  margin-right: 20px;
  min-width: 80px;
  text-align: center;
}

.queue-info {
  flex: 1;
}

.queue-business {
  font-size: 20px;
  color: #ff9800;
  margin-bottom: 5px;
  font-weight: 500;
}

.queue-time {
  font-size: 16px;
  color: #666;
}

.queue-wait-time {
  font-size: 18px;
  color: #f57c00;
  background-color: rgba(255, 152, 0, 0.15);
  padding: 6px 12px;
  border-radius: 20px;
  margin-left: 10px;
  font-weight: 500;
}

.empty-queue {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 120px;
  background-color: #f5f5f5;
  border-radius: 10px;
}

.empty-text {
  color: #999;
  font-size: 18px;
}

/* 历史叫号样式 */
.history-call-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  flex: 1;
  overflow: hidden;
  transition: all 0.3s ease;
}

.history-call-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.history-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: hidden;
  max-height: calc(100% - 50px);
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.history-item {
  display: flex;
  align-items: center;
  padding: 15px;
  background: linear-gradient(135deg, #f5f5f5, #e0e0e0);
  border-radius: 10px;
  border-left: 4px solid #1976d2;
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
  transition: all 0.3s ease;
}

.history-item:hover {
  transform: translateX(5px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.history-number {
  font-size: 28px;
  font-weight: bold;
  color: #f44336;
  margin-right: 20px;
  min-width: 100px;
  text-align: center;
}

.history-info {
  flex: 1;
}

.history-business {
  font-size: 20px;
  color: #1976d2;
  margin-bottom: 5px;
  font-weight: 500;
}

.history-window {
  font-size: 18px;
  color: #333;
}

.history-details {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  margin-left: 20px;
}

.history-time {
  font-size: 16px;
  color: #666;
  margin-bottom: 8px;
}

.history-status {
  font-size: 14px;
  color: white;
  padding: 4px 10px;
  border-radius: 15px;
  font-weight: 500;
}

.status-completed {
  background: linear-gradient(to right, #43a047, #4caf50);
  box-shadow: 0 2px 5px rgba(76, 175, 80, 0.3);
}

.status-serving {
  background: linear-gradient(to right, #1e88e5, #2196f3);
  box-shadow: 0 2px 5px rgba(33, 150, 243, 0.3);
}

.status-missed {
  background: linear-gradient(to right, #e53935, #f44336);
  box-shadow: 0 2px 5px rgba(244, 67, 54, 0.3);
}

/* 窗口状态样式 */
.window-status-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  flex: 2;
  overflow: hidden;
  transition: all 0.3s ease;
  position: relative;
}

.window-status-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.window-status-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 15px;
  overflow: hidden;
  max-height: calc(100% - 50px);
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.window-status-item {
  background: linear-gradient(135deg, #f5f5f5, #e0e0e0);
  border-radius: 10px;
  padding: 18px;
  position: relative;
  overflow: hidden;
  border-left: 4px solid #1976d2;
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
  transition: all 0.3s ease;
}

.window-status-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 15px rgba(0,0,0,0.1);
}

.window-name {
  font-size: 22px;
  font-weight: bold;
  color: #1976d2;
  margin-bottom: 12px;
}

.window-info {
  margin-bottom: 12px;
}

.window-staff, .window-type {
  font-size: 16px;
  color: #555;
  margin-bottom: 6px;
}

.window-queue-info {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.window-current, .window-waiting, .window-average {
  font-size: 15px;
  color: #555;
  background-color: rgba(0,0,0,0.05);
  padding: 6px 10px;
  border-radius: 8px;
  transition: all 0.3s ease;
}

.window-current:hover, .window-waiting:hover, .window-average:hover {
  background-color: rgba(0,0,0,0.08);
}

.window-current span, .window-waiting span, .window-average span {
  font-weight: bold;
  color: #333;
}

.window-status-indicator {
  position: absolute;
  top: 15px;
  right: 15px;
  padding: 5px 12px;
  border-radius: 15px;
  font-size: 14px;
  color: white;
  font-weight: 500;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.status-serving {
  background: linear-gradient(to right, #43a047, #4caf50);
}

.status-waiting {
  background: linear-gradient(to right, #fb8c00, #ff9800);
}

.status-closed {
  background: linear-gradient(to right, #e53935, #f44336);
}

/* 综合统计样式 */
.stats-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  transition: all 0.3s ease;
}

.stats-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.stats-list {
  display: flex;
  justify-content: space-between;
  gap: 15px;
}

.stats-item {
  flex: 1;
  text-align: center;
  background: linear-gradient(135deg, #e3f2fd, #bbdefb);
  border-radius: 10px;
  padding: 20px;
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.stats-item:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 20px rgba(0,0,0,0.1);
}

.stats-item::before {
  content: '';
  position: absolute;
  top: -10px;
  right: -10px;
  width: 30px;
  height: 30px;
  background-color: rgba(25, 118, 210, 0.1);
  border-radius: 50%;
  z-index: 0;
  transition: all 0.5s ease;
}

.stats-item:hover::before {
  transform: scale(7);
}

.stats-label {
  font-size: 18px;
  color: #1976d2;
  margin-bottom: 15px;
  font-weight: 500;
  position: relative;
  z-index: 1;
}

.stats-value {
  font-size: 32px;
  font-weight: bold;
  color: #333;
  position: relative;
  z-index: 1;
}

/* 通知公告样式 */
.notices-container {
  background-color: white;
  border-radius: 15px;
  padding: 20px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.08);
  flex: 1;
  overflow: hidden;
  transition: all 0.3s ease;
  position: relative;
}

.notices-container:hover {
  box-shadow: 0 10px 25px rgba(0,0,0,0.12);
  transform: translateY(-2px);
}

.notice-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: hidden;
  max-height: calc(100% - 50px);
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.notice-item {
  background: linear-gradient(135deg, #fff8e1, #ffecb3);
  border-radius: 10px;
  padding: 18px;
  border-left: 4px solid #ffc107;
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
  transition: all 0.3s ease;
  position: relative;
  overflow: hidden;
}

.notice-item:hover {
  transform: translateX(5px);
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.notice-title {
  font-size: 20px;
  font-weight: bold;
  color: #f57c00;
  margin-bottom: 12px;
}

.notice-content {
  font-size: 17px;
  color: #555;
  line-height: 1.6;
}

/* 轮播动画 */
.rotating {
  transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
  opacity: 0.3;
  transform: translateY(-15px);
}

/* 页码指示器 */
.pagination-indicator {
  display: flex;
  justify-content: center;
  margin-top: 15px;
  gap: 10px;
}

.indicator-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background-color: rgba(0,0,0,0.15);
  cursor: pointer;
  transition: all 0.3s ease;
}

.indicator-dot.active {
  background-color: #1976d2;
  transform: scale(1.3);
  box-shadow: 0 0 10px rgba(25, 118, 210, 0.5);
}

@media (max-width: 1200px) {
  .content {
    flex-direction: column;
  }

  .left-panel, .right-panel {
    width: 100%;
  }
}

/* 动态数字翻转动画 */
@keyframes flipNumber {
  0% { transform: perspective(400px) rotateX(0); opacity: 1; }
  50% { transform: perspective(400px) rotateX(-90deg); opacity: 0.5; }
  100% { transform: perspective(400px) rotateX(0); opacity: 1; }
}

.stats-value {
  animation: flipNumber 1s ease-out;
}

/* 强调焦点元素 */
.current-call.animated .ticket-number {
  animation: highlightNumber 3s ease;
}

@keyframes highlightNumber {
  0% { transform: scale(1); text-shadow: 0 0 0px rgba(244, 67, 54, 0); }
  20% { transform: scale(1.2); text-shadow: 0 0 20px rgba(244, 67, 54, 0.5); }
  40% { transform: scale(1.1); text-shadow: 0 0 10px rgba(244, 67, 54, 0.3); }
  60% { transform: scale(1.15); text-shadow: 0 0 15px rgba(244, 67, 54, 0.4); }
  80% { transform: scale(1.05); text-shadow: 0 0 5px rgba(244, 67, 54, 0.2); }
  100% { transform: scale(1); text-shadow: 0 0 0px rgba(244, 67, 54, 0); }
}

/* 全屏显示适配 */
@media (min-width: 1920px) {
  .panel-title {
    font-size: 28px;
  }

  .ticket-number {
    font-size: 80px;
  }

  .business-type {
    font-size: 42px;
  }

  .window-number {
    font-size: 36px;
  }

  .window-status-list {
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  }

  .stats-value {
    font-size: 38px;
  }
}
</style>
